#include<iostream> #define LEN sizeof(HaffmanNode) #define MAXSIZE 100 #define MAX 9999 using namespace std; typedef struct{ int value; int lChild,rChild,parent; }HaffmanNode,Haffman[MAXSIZE]; typedef struct{ char name; int w; char code[MAXSIZE]; }HaffmanCode[MAXSIZE]; //全局变量 Haffman h; HaffmanCode hc; //筛选出值最小的两个结点,s1,s2存储其结点的索引位置 void Select(Haffman h,int index,int *s1,int *s2) { *s1=0;*s2=0; for(int i=1;i<=index;i++) { //筛选出无双亲结点,且权值最小的两个结点 if(h[i].parent==0) { if(h[i].value<=h[*s1].value) { *s2=*s1; *s1=i; } else if(h[i].value<h[*s2].value) { *s2=i; } } } } //创建哈弗曼树及每个叶结点的哈弗曼编码 void CreateHaffmanTree(Haffman h,HaffmanCode hc,int n) { int s1,s2; h[0].value=MAX; for(int i=1;i<=n;i++) { h[i].lChild=h[i].rChild=h[i].parent=0; h[i].value=hc[i].w; } for(i=n+1;i<=2*n-1;i++) { h[i].lChild=h[i].rChild=h[i].parent=h[i].value=0; } //构建叶子结点外的其他结点 for(i=n+1;i<=2*n-1;i++) { Select(h,i-1,&s1,&s2); h[i].lChild=s1;h[i].rChild=s2; h[i].value=h[s1].value+h[s2].value; h[s1].parent=i;h[s2].parent=i; } } //求每个叶结点的哈弗曼编码 void CreateHaffmanCode(Haffman h,HaffmanCode hc,int n) { int Stack[MAXSIZE],top=-1; char flag[MAXSIZE],j; HaffmanNode th; for(int i=1;i<=n;i++) { th=h[i];int c=i;j=0; while(th.parent!=0) { Stack[++top]=th.parent; if(h[Stack[top]].lChild==c) { flag[top]='L';c=th.parent; } else if(h[Stack[top]].rChild==c) { flag[top]='R';c=th.parent; } th=h[Stack[top]]; } while(top!=-1) { if(flag[top]=='L') hc[i].code[j++]='0'; else hc[i].code[j++]='1'; top--; } hc[i].code[j]='\0'; } } //求叶结点的所在层的深度 int Depth(Haffman h,HaffmanNode hd) { int count=0; HaffmanNode temp; temp=hd; while(temp.parent!=0) { temp=h[temp.parent]; count++; } return count; } //打印叶结点的哈弗曼编码值,以及二叉树的带权路径长度 void PrintHaffmanCode(Haffman h,HaffmanCode hc,int n) { int weight,sum=0; for(int i=1;i<=n;i++) { weight=Depth(h,h[i])*h[i].value; cout<<"结点名称:"<<hc[i].name<<",结点的哈弗曼编码值:"<<hc[i].code<<"\n"; sum+=weight; } cout<<"带权路径长度为:"<<sum<<"\n"; } int main() { int n; char cmd; do{ cout<<"输入叶子结点数目\n"; cin>>n; cout<<"输入叶子结点名称和每个叶子结点的权值\n"; for(int i=1;i<=n;i++) { cin>>hc[i].name>>hc[i].w; } CreateHaffmanTree(h,hc,n); CreateHaffmanCode(h,hc,n); PrintHaffmanCode(h,hc,n); cout<<"继续吗y/Y\n"; cin>>cmd; }while(cmd=='y'||cmd=='Y'); return 0; }
哈弗曼树建立与哈弗曼编码
最新推荐文章于 2021-01-29 10:00:04 发布